<!-- 新增编辑角色 -->
<template>
  <div>
    <el-dialog
      :title="isAdd == 1 ? '新增角色' : '修改角色'"
      :visible.sync="addEditVisible"
    >
      <el-form
        class="formView"
        ref="form"
        :model="formdata"
        :rules="rules"
        label-position="right"
        label-width="100px"
      >
        <el-form-item label="角色名称:" prop="roleName">
          <el-input
            v-model="formdata.roleName"
            clearable
            placeholder="角色名称"
          ></el-input>
        </el-form-item>

        <el-form-item label="角色编码:" prop="roleCode">
          <el-input
            v-model="formdata.roleCode"
            :disabled="isAdd == 2"
            placeholder="角色编码"
          ></el-input>
        </el-form-item>

        <el-form-item label="授权菜单" prop="menuIdsList">
          <el-cascader
            :props="propss"
            :options="deptList"
            v-model="formdata.menuIdsList"
            collapse-tags
            clearable
          >
          </el-cascader>
        </el-form-item>
      </el-form>
      <div slot="footer">
        <el-button @click="addEditVisible = false">取 消</el-button>
        <el-button type="primary" @click="submitForm('form')">确定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { getMenuList } from '@/api/rightsManage'
import { addRole, updateRole } from '@/api/rightsManage'
export default {
  components: {},
  props: {
    isAdd: {
      type: Number,
      default() {
        return 1
      }
    },
    detailData: {
      type: Object,
      default() {
        return {}
      }
    }
  },
  data() {
    return {
      addEditVisible: false,
      lineList: [],
      formdata: {
        roleCode: '',
        roleName: '',
        menuIds: [],
        menuIdsList: [],
        state: '1'
      },
      deptList: [],
      rules: {
        roleName: [
          { required: true, message: '请输入角色名称', trigger: 'blur' }
        ],
        roleCode: [
          { required: true, message: '请输入角色编码', trigger: 'blur' }
        ],
        menuIdsList: [
          {
            type: 'array',
            required: true,
            message: '请选择上级部门',
            trigger: 'change'
          }
        ]
      },
      propss: {
        value: 'menuId',
        label: 'menuName',
        children: 'childrens',
        expandTrigger: 'hover',
        multiple: true
      }
    }
  },
  created() {},
  mounted() {},
  methods: {
    submitForm(formName) {
      this.$refs[formName].validate(valid => {
        if (valid) {
          this.onSubmit()
        } else {
          return false
        }
      })
    },
    // 获取菜单列表
    getMenuList() {
      getMenuList(Object.assign({})).then(res => {
        this.lineList = res.data
        this.deptList = this.listConvertTree(res.data)
        if (this.isAdd == 2) {
          const lineListArr = JSON.parse(JSON.stringify(this.deptList))

          // 去除列表不存在的节点
          let filterNode = arr => {
            var newData = arr.filter(x =>
              this.detailData.menuIds.includes(x.menuId)
            )
            newData.forEach(
              x => x.childrens && (x.childrens = filterNode(x.childrens))
            )
            return newData
          }

          let arr = filterNode(lineListArr)

          // 查找节点的完整路径
          let restNode = (tree, func, path = [], result = []) => {
            for (const data of tree) {
              path.push(data.menuId)
              func(data) && !data.childrens && result.push([...path])
              data.childrens && restNode(data.childrens, func, path, result)
              path.pop()
            }
            return result
          }

          let result = restNode(arr, node => node.menuId)

          console.log(result)

          setTimeout(() => {
            this.formdata.menuIdsList = result
            this.$refs['form'].clearValidate('menuIdsList')
          })
        }
      })
    },
    onSubmit() {
      console.log(this.formdata)
      if (this.isAdd == 1) {
        addRole(this.formdata).then(res => {
          this.$message({
            message: this.isAdd == 1 ? '新增成功' : '修改成功',
            type: 'success'
          })
          this.$parent.getDataList()
          this.resetForm('form')
        })
      } else if (this.isAdd == 2) {
        updateRole(this.formdata).then(res => {
          this.$message({
            message: this.isAdd == 1 ? '新增成功' : '修改成功',
            type: 'success'
          })
          this.$parent.getDataList()
          this.resetForm('form')
        })
      }
    },
    resetForm(formName) {
      // this.$refs[formName].resetFields()
      this.formdata = {
        roleCode: '',
        roleName: '',
        menuIds: [],
        menuIdsList: [],
        state: '1'
      }
      this.addEditVisible = false
    },
    // 线性转树结构
    listConvertTree(data) {
      //没有父节点的数据
      let parents = data.filter(
        value =>
          value.parentId == 'undefined' ||
          value.parentId == null ||
          value.parentId == 0
      )
      //有父节点的数据
      let childrens = data.filter(
        value =>
          value.parentId !== 'undefined' &&
          value.parentId != null &&
          value.parentId > 0
      )
      //定义转换方法的具体实现
      let translator = (parents, childrens) => {
        //遍历父节点数据
        parents.forEach(parent => {
          //遍历子节点数据
          childrens.forEach((current, index) => {
            //此时找到父节点对应的一个子节点
            if (current.parentId === parent.menuId) {
              //对子节点数据进行深复制，这里只支持部分类型的数据深复制，对深复制不了解的童靴可以先去了解下深复制
              let temp = JSON.parse(JSON.stringify(childrens))
              //让当前子节点从temp中移除，temp作为新的子节点数据，这里是为了让递归时，子节点的遍历次数更少，如果父子关系的层级越多，越有利
              temp.splice(index, 1)
              //让当前子节点作为唯一的父节点，去递归查找其对应的子节点
              translator([current], temp)
              //把找到子节点放入父节点的childrens属性中
              typeof parent.childrens !== 'undefined'
                ? parent.childrens.push(current)
                : (parent.childrens = [current])
            }
          })
        })
      }
      //调用转换方法
      translator(parents, childrens)
      //返回最终的结果
      return parents
    },
    // 树转线性结构
    hasChildrenId(root) {
      const list = []
      if (root) {
        const Root = JSON.parse(JSON.stringify(root))
        const queue = []
        queue.push(Root)
        while (queue.length) {
          const node = queue.shift()
          if (node.childrens && node.childrens.length) {
            queue.push(...node.childrens)
          }
          delete node.childrens
          if (node.parentId !== null && node.parentId !== undefined) {
            list.push(node)
          }
        }
      }
      return list
    },
    // 获取部门 parentIds
    getChildrenIds(deptId) {
      let Root = JSON.parse(
        JSON.stringify(this.hasChildrenId(this.deptList[0]))
      )
      let list = []
      let findParentId = (root, deptId) => {
        root.forEach((current, index) => {
          if (current.deptId == deptId && current.parentId > 0) {
            list.push(current.parentId)
            let temp = JSON.parse(
              JSON.stringify(
                root.slice(0, index).concat(root.slice(index + 1, root.length))
              )
            )
            findParentId(temp, current.parentId)
          }
        })
      }
      findParentId(Root, deptId)
      list.reverse()
      return list
    }
  },
  watch: {
    addEditVisible: {
      deep: true,
      handler(now, old) {
        if (now) {
          this.getMenuList()

          if (this.isAdd == 2) {
            this.formdata = Object.assign({}, this.formdata, this.detailData)
          }
        } else {
          this.resetForm('form')
        }
      }
    },
    'formdata.menuIdsList': {
      deep: true,
      handler(now, old) {
        if (now) {
          let arr = []
          for (let i = 0; i < now.length; i++) {
            arr = arr.concat(now[i])
          }
          const res = new Map()
          this.formdata.menuIds = arr
            .filter(a => !res.has(a) && res.set(a, 1))
            .join(',')
        } else {
          this.formdata.menuIds = []
        }
      }
    }
  }
}
</script>

<style lang="scss" scoped>
::v-deep {
  .el-dialog {
    width: 500px;
    border-radius: 10px;
  }
  .el-dialog__title {
    font-size: 16px;
  }
  .el-input {
    width: 250px;
  }
  .el-dialog__body {
    padding-top: 0;
    padding-bottom: 0px;
  }
  .el-form {
    padding: 10px 0;
  }
  .el-input__inner {
    height: 35px;
    line-height: 35px;
  }
  .el-form-item {
    margin-bottom: 15px;
    &:last-child {
      margin-bottom: 0;
    }
  }
  .el-dialog__footer {
    padding-top: 10px;
    padding-bottom: 10px;
    border-top: 1px solid #eee;
  }
}
.formView {
  border-top: 1px solid #eee;
  .sortInput {
    width: 100px;
  }
}
</style>
